package handler

import (
	"fmt"
	"ideatools/application/constant"
	"ideatools/application/constant/enums"
	"ideatools/application/core/events"
	"ideatools/application/core/toast"
	"ideatools/application/db/dbdto"
	"ideatools/application/db/dbservice"
	"ideatools/application/pkgs/clips"
	"strings"
	"time"
)

const StreamSendSpaceTime = 110 //多久发一次流给前端
type HandlerMessageService struct {
	//GptService        chat.IGpt                  //用户工具
	DbToolService       *dbservice.UserToolService //用户工具
	ChatDialogService   *dbservice.DbChatDialogService
	IsHandingTask       bool //是否正在处理任务
	CurrToolInfo        *dbdto.UserToolInfo
	CurrChatDialogId    uint
	CurrChatAiContent   *dbdto.ChatContentInfo
	CurrChatUserContent *dbdto.ChatContentInfo
	StreamSendLastTime  time.Time //保存最后发送流的时间
	StreamSendStartTime time.Time //保存开始发送时间
}

func NewHandlerMessageService() *HandlerMessageService {

	return &HandlerMessageService{
		DbToolService:     dbservice.NewUserToolService(),
		ChatDialogService: dbservice.NewChatDialogService(),
	}
}

// Send 处理方式：流式 一次性（默认）
// DialogId 对话id 为0表示会创建新的对话
func (s *HandlerMessageService) Send(ToolId uint, DialogId uint) string {
	//判断配置是否填写
	if !CanSend() {
		return ""
	}

	//判断是否有正在执行的任务
	if s.IsHandingTask {
		toast.SysInfo("处理失败", "有任务正在处理，稍等一下吧")
		return ""
	}

	s.IsHandingTask = true //处理中状态设置成true
	clips.CopySelect()     //复制选中文本

	//获取tool信息
	ToolInfo := s.GetToolInfo(ToolId)
	if ToolInfo == nil {
		return ""
	}
	s.CurrToolInfo = ToolInfo

	if ToolInfo.CompleteDo == enums.CompleteDoShow {
		events.OnChangeWindow(enums.WindowsTypeMessage)
	}

	//获取剪切板列表

	clipTexts := s.GetClipTexts(int(ToolInfo.InputCount))
	if ToolInfo.InputCount > 0 && len(clipTexts) <= 0 {
		s.IsHandingTask = false
		toast.SysInfo("获取选中文本失败", "")
		return ""
	}

	//根据剪切板信息和toolId组装prompt模板
	_, sendContent := s.DbToolService.ParsePromptText(ToolId, clipTexts)

	//复制还是调用AI,如果点击后是复制到剪贴板
	if dbservice.Conf().Get(constant.ConfigKeyClickToolEvent) == enums.ClickToolCopy {
		copySendContent(sendContent)
		s.IsHandingTask = false
		return ""
	}

	//开始调用gpt
	toast.SysInfo(fmt.Sprintf("【%s】--开始处理", ToolInfo.ToolName), fmt.Sprintf("%s", strings.Join(clipTexts, "+")))

	//获取会话
	DialogId = GetChatDialogId(ToolId, DialogId, clipTexts)
	if DialogId == 0 {
		return ""
	}
	s.CurrChatDialogId = DialogId
	go func() {
		//将发送内容入库，一次性入库两条
		s.SendContentAddToDb(DialogId, sendContent, true, clipTexts)

		if s.CurrChatUserContent == nil || s.CurrChatAiContent == nil {
			return
		}

		//调用gpt
		if s.CurrToolInfo.CompleteDo == enums.CompleteDoShow {
			//流式返回
			s.gptSendByStream()
		} else {
			//一次性返回
			s.gptSendByOnce()
		}

	}()

	return ""
}

// SendContinue 继续追问--面板模式的是才能用
func (s *HandlerMessageService) SendContinue(DialogId uint, sendContent string) {
	go func() {
		s.ClearCurrInfo()
		s.IsHandingTask = true

		//获取tool信息
		ToolInfo := s.GetToolInfoByChatDialogId(DialogId)
		if ToolInfo == nil {
			return
		}
		s.CurrToolInfo = ToolInfo

		//将发送内容入库，一次性入库两条
		s.SendContentAddToDb(DialogId, sendContent, true, nil)
		if s.CurrChatUserContent == nil || s.CurrChatAiContent == nil {
			return
		}
		//调用gpt
		if s.CurrToolInfo.CompleteDo == enums.CompleteDoShow {
			//流式返回
			s.gptSendByStream()
		} else {
			//s.gptSendByOnce()
			s.IsHandingTask = false
		}

	}()

}

func (s *HandlerMessageService) ClearCurrInfo() {
	s.CurrChatAiContent = nil
	s.CurrChatUserContent = nil
	s.CurrChatDialogId = 0
	s.CurrToolInfo = nil
}
